/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.ufpr.inf.escel.brain.operators.util;

/**
 *
 * @author gustavo
 */
public class CruzamentoUtils {

    /**
     * Cruzamento de multiplos pontos de corte
     * pai   = 00000000000000000
     * mae   = 11111111111111111
     * filho = 00000011111100000
     *
     * @param string s1
     * @param string s2
     * @return string resultante da combinação da s1 e s2
     * @since 2.1
     */
    public static String merge(String pai, String mae) {

        String filho = "";

        if (pai.length() > 0) {
            filho = pai.substring(0, pai.length() / 2);
        }

        if (mae.length() > 0) {
            filho += mae.substring(mae.length() / 2, mae.length());
        }

        return filho;
    }

    /**
     * Soma ou divire os valores de dois inteiros
     *
     * @param i1 primeiro inteiro
     * @param i2 segundo inteiro
     * @return i1 + i2 ou i1 - i2
     * @since 2.1
     */
    public static Integer merge(Integer i1, Integer i2) {
        int moeda = (int) (Math.random() + 0.5);

        if (moeda == 0) {
            return i1 + i2;
        } else {
            return i1 - i2;
        }
    }

    /**
     * Soma ou diminui dois doubles
     *
     * @param n1 primeiro double
     * @param n2 segundo double
     * @return i1 + i2 ou i1 - i2
     * @since 2.1
     */
    public static Double merge(Double n1, Double n2) {

        int moeda = (int) (Math.random() + 0.5);

        if (moeda == 0) {
            return n1 + n2;
        } else {
            return n1 - n2;
        }
    }

    /**
     * Soma ou diminui dois floats
     *
     * @param n1 primeiro floats
     * @param n2 segundo floats
     * @return i1 + i2 ou i1 - i2
     * @since 2.1
     */
    public static Float merge(Float n1, Float n2) {

        int moeda = (int) (Math.random() + 0.5);

        if (moeda == 0) {
            return n1 + n2;
        } else {
            return n1 - n2;
        }
    }

    /**
     * Metodo que simplifica tudo. Só faz a verificação do tipo
     * de dados e manda pro metodo correspondente.
     *
     * @param n1 primeiro valor
     * @param n2 segundo valor
     * @return o valor concatenado e codificado
     * @since 2.1
     */
    public static Object merge(Object n1, Object n2) {

        if (n1 instanceof Character) {
            n1 = (Character) n1;
            n2 = (Character) n2;

            int moeda = (int) (Math.random() + 0.5);
            return (moeda == 0) ? n1 : n2;

        } else if (n1 instanceof Integer) {
            return merge((Integer) n1, (Integer) n2);
        } else if (n1 instanceof String) {
            return merge((String) n1, (String) n2);
        } else if (n1 instanceof Float) {
            return merge((Float) n1, (Float) n2);
        } else if (n1 instanceof Double) {
            return merge((Double) n1, (Double) n2);
        }
        throw new UnsupportedOperationException("Operação não suportada. Verifique o tipo do dado de teste!");
    }
}
